#pragma once

#include<iostream>
#include<string>
#include<ctime>


#define RESET "\033[0m"
#define RED "\033[31m"      /* Red */
#define GREEN "\033[32m"    /* Green */
#define MAGENTA "\033[35m"  /* MAGENTA*/
#define BLUE "\033[34m"     /* Blue */
#define CYAN "\033[36m"     
#define BOLDRED "\033[1m\033[31m"   /* Bold Red */

using std::cout;
using std::endl;

#define INFO    1
#define WARNING 2
#define ERROR   3
#define FATAL   4

//为了便利，不然每次调用都要传入大量参数  #作用是将传入参数转为字符串，因为是在目标处进行宏替换，所以文件名和行数都是目标处的
#define LOG(level, message) Log(#level, message, __FILE__, __LINE__)

//时间戳转化为时间 毫秒级
std::string convertTimeStamp2TimeStr(time_t timeStamp){
    struct tm *timeinfo = nullptr;
    char buffer[80];
    timeinfo = localtime(&timeStamp);
    strftime(buffer,80,"%Y-%m-%d %H:%M:%S",timeinfo);
    return std::string(buffer);
}

//设置日志，包括日志级别，时间戳，日志信息（错误，风险等的提示信息），相应文件名称，行数
void Log(std::string level, std::string message, std::string file_name, size_t line) {
    time_t curtime = time(nullptr);
    std::string time = convertTimeStamp2TimeStr(curtime);

    cout << "-----------------------------------------------------------------" << endl;
    cout << "日志等级：" << level <<  "\t 时间：" << time << endl;
    cout << "日志信息：";
    if (level == "ERROR") {
        cout << RED << message << RESET;
    }
    else if (level == "WARNING") {
        cout << MAGENTA << message << RESET;
    }
    else if (level == "INFO") {
        cout << BLUE << message << RESET;
    }
    else {
        cout << BOLDRED << message << RESET;
    }
    cout << endl;
    cout << "文件名称：" << file_name << "\t 所在行数：" << line << endl;
    cout << "-----------------------------------------------------------------" << endl;
}